package cn.com.chengmandian.bike.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * <p>
 * 线程池配置
 * </p>
 *
 * @author dendi
 * @since 2022/4/20
 */
@Configuration
@EnableAsync
@Slf4j
public class ThreadPoolConfig {
    /**
     * 替代spring默认线程池 供异步事件使用
     */
    @Primary
    @Bean(name="globalThreadPool")
    public Executor createGlobalPool(){
        //通过Runtime方法来获取当前服务器cpu内核，根据cpu内核来创建核心线程数和最大线程数
        int threadCount = Runtime.getRuntime().availableProcessors()*2;
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(threadCount);
        executor.setMaxPoolSize(threadCount*10);
        executor.setQueueCapacity(100);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("cmd-thread-pool-");
        //线程池拒绝策略:丢弃任务 并打印错误日志
        executor.setRejectedExecutionHandler((r, executor1) -> {
            log.error("线程池满载-丢弃任务!");
            log.error("线程池:{}", JSONObject.toJSONString(executor1));
            log.error("任务:{}", JSONObject.toJSONString(r));
        });
        executor.initialize();
        log.info("初始化全局线程池:"+JSONObject.toJSONString(executor));
        return executor;
    }
}
